from multiprocessing.dummy import Pool as ThreadPool
import os
import json
import time
from PIL import Image
from webapp.config import Config
from webapp import celery, redis_store, db
from webapp.models import PicFile, Pic, Album, Tag, Volume, Actress
from webapp.plugins.functions import now, error_catching, VolumeCache, TagCache, AlbumCache, ActressCache
from webapp.plugins.image_utils import img2webp
from shutil import move


@celery.task
def convert_task(pic_id: int, high_quality: bool = False):
    """
    把图片转为webp格式
    :param pic_id: pics_id
    :param high_quality:
    :return:
    """
    # pic = Pic.query.filter_by(id=pic_id).first()
    # file_path = pic.full_path
    # img_data = img2webp(file_path, high_quality)
    # md5 = img_data.get('md5')
    # width = img_data.get('width')
    # height = img_data.get('height')
    # file_size = img_data.get('file_size')
    # img_buffer = img_data.get('img_buffer')
    # thumb_buffer = img_data.get('thumb_buffer')
    # pic.remove_image()
    #
    # pic.file_name = md5
    # pic.file_type = 'webp'
    # pic.width = width
    # pic.height = height
    # pic.file_size = file_size
    # db.session.commit()
    #
    # with open(pic.full_path, 'wb') as img:
    #     img.write(img_buffer.getvalue())
    # with open(pic.full_thumb_path, 'wb') as f:
    #     f.write(thumb_buffer.getvalue())


@celery.task
def check_pics_task():
    """ 检查图片缺失情况的任务 """

    # # 清空已存在的对比结果
    # if redis_store.keys('check_task_*'):
    #     redis_store.delete(*redis_store.keys('check_task_*'))
    #
    # # 准备对比使用的数据
    # db_list = []
    # for pic in Pic.query.all():
    #     db_list.append(''.join([pic.file_name, '.', pic.file_type]))
    #
    # files_list = []
    # for root, dirs, files in os.walk(Config.PICLAB_BASE_DIR):  # 遍历统计
    #     files_list.extend(files)
    #
    # thumbnail_list = []
    # for root, dirs, files in os.walk(Config.PICLAB_THUMBNAIL_DIR):  # 遍历统计
    #     thumbnail_list.extend(files)
    #
    # # 对比数据
    # dbr_lost = list(set(files_list).difference(set(db_list)))  # 文件存在，数据库记录不存在
    # file_lost_db = list(set(db_list).difference(set(files_list)))  # 数据库记录存在，文件不存在
    # thumbnail_lost = list(set(files_list).difference(set(thumbnail_list)))  # 文件记录存在，缩略图不存在
    # file_lost_thumbnail = list(set(thumbnail_list).difference(set(files_list)))  # 有缩略图，但图片不存在
    #
    # # 对比结果存入redis
    # redis_store.set('check_task_checktime', now())  # 更新检查时间
    # redis_store.set('check_task_pics_count', len(files_list))  # 图片文件数量
    # redis_store.set('check_task_thumbnail_count', len(thumbnail_list))  # 缩略图数量
    #
    # redis_store.set('check_task_dbr_lost_count', len(dbr_lost))  # 数据库记录丢失的 数量
    # redis_store.set('check_task_dbr_lost_list', json.dumps(dbr_lost))  # 数据库记录丢失的 清单
    #
    # redis_store.set('check_task_file_lost_db_count', len(file_lost_db))  # 数据库记录正常，图片丢失的 数量
    # redis_store.set('check_task_file_lost_db_list', json.dumps(file_lost_db))  # 数据库记录正常，图片丢失的 清单
    #
    # redis_store.set('check_task_thumbnail_lost_count', len(thumbnail_lost))  # 图片正常，缺少缩略图的 数量
    # redis_store.set('check_task_thumbnail_lost_list', json.dumps(thumbnail_lost))  # 图片正常，缺少缩略图的 清单
    #
    # redis_store.set('check_task_file_lost_thumbnail_count', len(file_lost_thumbnail))  # 有缩略图，但图片不存在的 数量
    # redis_store.set('check_task_file_lost_thumbnail_list', json.dumps(file_lost_thumbnail))  # 有缩略图，但图片不存在的 清单
    #
    # # 计算未加入任何相册和标签的图片数量
    # redis_store.set('check_tasks_unfiled_pic_count', Pic.unfiled_pic_count())


@celery.task
def create_thumbnail_task():
    """ 图片缺少缩略图，且数据库记录正常的情况，生成缩略图 """
    thumbnail_lost_list = redis_store.get('check_task_thumbnail_lost_list')
    thumbnail_lost_list = eval(thumbnail_lost_list) if thumbnail_lost_list else ''
    thumbnail_lost_list = map(lambda x: x[:-4], thumbnail_lost_list)
    #
    # for pic_name in thumbnail_lost_list:
    #     try:
    #         pic = Pic.query.filter_by(file_name=pic_name).first()
    #         file, thumb = pic.file_exist()
    #         if file and not thumb:
    #             # 处理缩略图
    #             try:
    #                 with Image.open(pic.full_path) as img:
    #                     thumbnail_size = (Config.THUMB_WIDTH, int(pic.height / pic.width * Config.THUMB_WIDTH))
    #                     thumbnail_path = Config.PICLAB_THUMBNAIL_DIR / pic.file_name[0:2] / pic.full_name
    #
    #                     img.thumbnail(thumbnail_size)
    #                     img.save(fp=thumbnail_path)
    #
    #             except Exception as e:
    #                 print(pic.full_name, e)
    #
    #     except Exception as e:
    #         print('create_thumbnail_task - error:', str(e))


@celery.task
def delete_thumbnail_task():
    """ 只有缩略图没有图片文件存在的时候，删除缩略图 """
    file_lost_list = redis_store.get('check_task_file_lost_thumbnail_list')
    file_name_list = eval(file_lost_list) if file_lost_list else ''

    # # 判断数据库中是否有记录
    # def do(file):
    #     pic = Pic.query.filter_by(file_name=file[0:-4]).first()
    #     if not pic:
    #         thumbnail_path = Config.PICLAB_THUMBNAIL_DIR / file[0:2] / file
    #         os.remove(thumbnail_path)
    #     else:
    #         pass
    #
    # pool = ThreadPool(4)
    # pool.map(do, file_name_list)
    # pool.close()
    # pool.join()


@celery.task
def move_to_recycle_task():
    """ 把缺少数据库记录的图片移至回收站 """
    dbr_lost_list = redis_store.get('check_task_dbr_lost_list')
    dbr_lost_list = eval(dbr_lost_list) if dbr_lost_list else ''

    # for pic in dbr_lost_list:
    #     pic_path = Config.PICLAB_BASE_DIR / pic[0:2] / pic
    #     pic_thumbnail_path = Config.PICLAB_THUMBNAIL_DIR / pic[0:2] / pic
    #     try:
    #         move(pic_path, Config.PICLAB_RECYCLE_DIR)
    #         os.remove(pic_thumbnail_path)
    #     except Exception as e:
    #         os.remove(pic_path)
    #         os.remove(pic_thumbnail_path)
    #         redis_store.lpush('deal_error', repr({'time': now(), 'act': 'move_to_recycle_task() error, file already be delete.', 'file': pic, 'error': str(e)}))


@celery.task
def clear_cache(label=''):
    if not label or label == 'album':
        AlbumCache().init_cache()
    if not label or label == 'tag':
        TagCache().init_cache()
    if not label or label == 'volume':
        VolumeCache().init_cache()
    if not label or label == 'actress':
        ActressCache().init_cache()
